#ifndef __WIZ_BNF_PARSER_REAL_HPP__SHANHAOBO_19800429__
#define __WIZ_BNF_PARSER_REAL_HPP__SHANHAOBO_19800429__

#include "./WizBNFParserRealImpl.hpp"
#include "./WizBNFParserInteger.hpp"
#include "./WizBNFParserCharCheck.hpp"

#include "../Directive/WizBNFDirectiveInhibitCase.hpp"

namespace Wiz
{
    namespace BNF
    {
        namespace Parser
        {
            namespace Policies
            {
                namespace UReal
                {
                    template <typename T>
                    struct Type
                    {
                        static ::Wiz::Bool::TypeConst AllowLeadingDot = ::Wiz::Bool::True;
                        static ::Wiz::Bool::TypeConst AllowTrailingDot = ::Wiz::Bool::True;
                        static ::Wiz::Bool::TypeConst ExpectDot = ::Wiz::Bool::False;

                        typedef ::Wiz::BNF::Parser::Integer::Unsignal::Type<T, 10, 1, -1>   tUintParser;
                        typedef ::Wiz::BNF::Parser::Integer::Signal::Type<T, 10, 1, -1>     tIntParser;

                        template <typename ScannerT>
                        static typename ::Wiz::BNF::Match::Result<ScannerT, ::Wiz::Null::Type>::tType
                            ParseSign(ScannerT& Scan)
                        { 
                            return Scan.NoMatch(); 
                        }

                        template <typename ScannerT>
                        static typename ::Wiz::BNF::Parser::Result<tUintParser, ScannerT>::tType
                            ParseN(ScannerT& Scan)
                        { 
                            return tUintParser().Parse(Scan); 
                        }

                        template <typename ScannerT>
                        static typename ::Wiz::BNF::Parser::Result<::Wiz::BNF::Parser::Char::Check::Type<>, ScannerT>::tType
                            ParseDot(ScannerT& Scan)
                        { 
                            return ::Wiz::BNF::Parser::Predef::CharCheck('.').Parse(Scan); 
                        }

                        template <typename ScannerT>
                        static typename ::Wiz::BNF::Parser::Result<tUintParser, ScannerT>::tType
                            ParseFracN(ScannerT& Scan)
                        { 
                            return tUintParser().Parse(Scan); 
                        }

                        template <typename ScannerT>
                        static typename ::Wiz::BNF::Parser::Result<::Wiz::BNF::Parser::Char::Check::Type<>, ScannerT>::tType
                            ParseExp(ScannerT& Scan)
                        { 
                            return ::Wiz::BNF::Directive::Predef::InhibitCase::AsLower['e'].Parse(Scan); 
                        }

                        template <typename ScannerT>
                        static typename ::Wiz::BNF::Parser::Result<tIntParser, ScannerT>::tType
                            ParseExpN(ScannerT& Scan)
                        { 
                            return tIntParser().Parse(Scan); 
                        }
                    };
                } /// end of namespace UReal

                namespace Real
                {
                    template <typename T>
                    struct Type : public ::Wiz::BNF::Parser::Policies::UReal::Type<T>
                    {
                        template <typename ScannerT>
                        static typename ::Wiz::BNF::Parser::Result<::Wiz::BNF::Parser::Sign::Type, ScannerT>::tType
                        ParseSign(ScannerT& Scan)
                        { 
                            return ::Wiz::BNF::Parser::Predef::Sign::Check.Parse(Scan); 
                        }
                    };
                } /// end of namespace Real

                namespace StrictUreal
                {
                    template <typename T>
                    struct Type : public ::Wiz::BNF::Parser::Policies::UReal::Type<T>
                    {
                        static ::Wiz::Bool::TypeConst ExpectDot = ::Wiz::Bool::True;
                    };
                } /// end of namespace StrictUreal

                namespace StrictReal
                {
                    template <typename T>
                    struct Type : public ::Wiz::BNF::Parser::Policies::Real::Type<T>
                    {
                        static ::Wiz::Bool::TypeConst ExpectDot = ::Wiz::Bool::True;
                    };
                } /// end of namespace StrictReal
            } /// end of namespace Policies

            namespace Real
            {
                template <
                    typename ElementT,
                    typename PoliciesT
                >
                struct Type : public ::Wiz::BNF::Parser::Type<Type<ElementT, PoliciesT>>
                {
                    typedef Type        tThis;
                    typedef ElementT    tElement;

                    template <typename ScannerT>
                    struct Result
                    {
                        typedef typename ::Wiz::BNF::Match::Result<
                            ScannerT,
                            tElement
                        >::tType tType;
                    };

                    Type() {}

                    template <typename ScannerT>
                    typename ::Wiz::BNF::Parser::Result<tThis, ScannerT>::tType
                    ParseImpl(ScannerT const& Scan) const
                    {
                        typedef ::Wiz::BNF::Parser::Result<tThis, ScannerT>::tType  tResult;

                        return ::Wiz::BNF::Parser::Impl::Real::Type<tResult, tElement, PoliciesT>::Parse(Scan);
                    }
                };
            } /// end of namespace Real
        } /// end of namespace Parser
    } /// end of namespace BNF
} /// end of namespace Wiz

#endif /*__WIZ_BNF_PARSER_REAL_HPP__SHANHAOBO_19800429__*/
